package com.ruoyi.web.controller.common.controller;

import com.ruoyi.common.constant.CouponConstants;
import com.ruoyi.common.constant.OrderConstants;
import com.ruoyi.common.constant.SysConfigConstants;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.entity.DO.order.MemberRechargeOrderDO;
import com.ruoyi.common.entity.DO.order.OrderRefundDO;
import com.ruoyi.common.entity.DO.order.ShopPetrolOrderDO;
import com.ruoyi.common.entity.DO.shop.ShopAppletDO;
import com.ruoyi.common.entity.DO.shop.ShopConfigDO;
import com.ruoyi.common.entity.VO.member.MemberCouponVO;
import com.ruoyi.common.entity.VO.shop.ShopConfigSearchVO;
import com.ruoyi.common.entity.VO.shop.ShopConfigVO;
import com.ruoyi.common.entity.wxpay.WxConfig;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.NumberUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.framework.manager.AsyncManager;
import com.ruoyi.framework.manager.factory.AsyncFactory;
import com.ruoyi.system.mapper.IBackShopConfigMapper;
import com.ruoyi.web.controller.member.mapper.IBackMemberCouponMapper;
import com.ruoyi.web.controller.order.mapper.IBackMemberRechargeOrderMapper;
import com.ruoyi.web.controller.order.mapper.IBackOrderRefundMapper;
import com.ruoyi.web.controller.order.mapper.IBackShopPetrolOrderMapper;
import com.ruoyi.web.controller.shop.service.IBackShopAppletService;
import com.ruoyi.web.controller.shop.service.IBackShopOrderRefundService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/back/crontab")
public class BackCrontabController extends BaseController {

    @Resource
    private IBackShopPetrolOrderMapper backShopPetrolOrderMapper;

    @Resource
    private IBackMemberRechargeOrderMapper backMemberRechargeOrderMapper;

    @Resource
    private IBackMemberCouponMapper memberCouponMapper;

    @Resource
    private IBackShopAppletService backShopAppletService;

    @Resource
    private IBackShopOrderRefundService backShopOrderRefundService;

    @Resource
    private IBackOrderRefundMapper backOrderRefundMapper;

    @Resource
    private IBackShopConfigMapper backShopConfigMapper;

    /**
     * 超过1天未支付的加油订单和充值订单
     * 处理方式：直接硬删除
     *
     * @return 删除的总数量
     */
    @GetMapping("/checkShopOrderPayExpire")
    public AjaxResult checkShopOrderPayExpire() {
        //TODO:查询前一天创建的订单
        Calendar calendar = Calendar.getInstance();
        calendar.add(GregorianCalendar.DATE, -1);
        String yesterday = DateUtils.parseDateToStr("yyyy-MM-dd HH:mm", calendar.getTime());
        List<MemberRechargeOrderDO> rechargeOrderList = backMemberRechargeOrderMapper.selectPayExpiredOrderList(yesterday);
        List<ShopPetrolOrderDO> petrolOrderList = backShopPetrolOrderMapper.selectPayExpiredOrderList(yesterday);
        if (rechargeOrderList.size() > 0) {
            //硬删除
            backMemberRechargeOrderMapper.deleteByIds(String.join(",", rechargeOrderList.stream().map(x -> x.getId() + "").collect(Collectors.toList())));
        }
        List<String> memberCouponIdArr = new ArrayList<>();
        if (petrolOrderList.size() > 0) {
            //优惠券返还
            petrolOrderList.forEach(map -> {
                if (0 != map.getCouponId()) {
                    memberCouponIdArr.add(map.getCouponId().toString());
                    memberCouponMapper.cancelRollBack(map.getMemberId(), map.getCouponId());
                }
            });
            //硬删除
            backShopPetrolOrderMapper.deleteByIds(String.join(",", petrolOrderList.stream().map(x -> x.getId() + "").collect(Collectors.toList())));
        }
        if (memberCouponIdArr.size() > 0) {
            AsyncManager.me().execute(AsyncFactory.refreshCoupon(String.join(",", memberCouponIdArr)));
        }
        return AjaxResult.success("处理成功！", rechargeOrderList.size() + petrolOrderList.size());
    }

    /**
     * 定时刷新退款状态
     *
     * @return
     */
    @GetMapping("/SyncRefreshRefundStatus")
    public AjaxResult SyncRefreshRefundStatus() {
        OrderRefundDO orderRefundSearchDO = new OrderRefundDO();
        orderRefundSearchDO.setRefundStatus(OrderConstants.RefundStatusEnum.REFUNDING.getValue());
        List<OrderRefundDO> refundList = backShopOrderRefundService.searchList(orderRefundSearchDO);
        for (OrderRefundDO one : refundList
        ) {
            //TODO：查询店铺的appId和secret
            ShopAppletDO shopApplet = backShopAppletService.getShopAppletInfoByShopId(one.getShopId());
            if (shopApplet == null || shopApplet.getIsEnable() == null || shopApplet.getIsDelete() == 1) {
                continue;
            }
            if (shopApplet.getIsEnable() == 0) {
                continue;
            }
            WxConfig wxConfig = new WxConfig();
            wxConfig.setAppID(shopApplet.getAppletAppId());
            wxConfig.setKey(shopApplet.getAppletPayKey());
            wxConfig.setMchID(shopApplet.getAppletMchId());
            try {
                wxConfig.setCertData(one.getShopId());
                Map<String, String> resultMap = backShopOrderRefundService.refresh(one.getRefundSn(), wxConfig);
                if (!resultMap.containsKey("err_code")) {
                    //TODO:退款成功
                    backOrderRefundMapper.updateRefundStatusByRefundSn(one.getRefundSn(), OrderConstants.RefundStatusEnum.COMPLETE.getValue());
                    if (one.getOrderType() == OrderConstants.RefundOrderTypeEnum.MEMBER_RECHARGE_ORDER.getValue()) {
                        backMemberRechargeOrderMapper.updatePayStatusByOrderSn(one.getRefundOrderSn(), OrderConstants.OrderPayStatusEnum.REFUND_SUCCESS.getValue());
                    } else if (one.getOrderType() == OrderConstants.RefundOrderTypeEnum.PETROL_ORDER.getValue()) {
                        backShopPetrolOrderMapper.updatePayStatusByOrderSn(one.getRefundOrderSn(), OrderConstants.OrderPayStatusEnum.REFUND_SUCCESS.getValue());
                    }
                }
            } catch (Exception e) {

            }
        }
        return AjaxResult.success("自动刷新会员订单退款状态成功！");
    }

    /**
     * 刷新优惠券状态
     *
     * @return
     */
    @GetMapping("/refreshCoupon")
    public AjaxResult refreshCoupon() {
        AsyncManager.me().execute(AsyncFactory.refreshCoupon(""));
        return AjaxResult.success("刷新成功！");
    }

    /**
     * 刷新核销密码
     *
     * @return
     */
    @GetMapping("/refreshExchangePassword/{len}")
    public AjaxResult refreshExchangePassword(@PathVariable("len") String len) {
        String minLen = len.split("-")[0];
        String maxLen = len.split("-")[1];
        List<Integer> lenArr = new ArrayList<>();
        if(10 < Integer.valueOf(maxLen)){
            maxLen = "10";
        }
        if(6 > Integer.valueOf(maxLen)){
            minLen = "6";
        }
        for (int i=Integer.valueOf(minLen);i<=Integer.valueOf(maxLen);i++ ){
            lenArr.add(i);
        }
        Collections.shuffle(lenArr);
        ShopConfigSearchVO shopConfigSearchVO = new ShopConfigSearchVO();
        shopConfigSearchVO.setConfigKey("exchange.password");
        List<ShopConfigVO> configList = backShopConfigMapper.searchList(shopConfigSearchVO);
        if (configList.size() > 0) {
            configList.forEach(x -> {
                if (null != x.getId()) {
                    ShopConfigDO configDO = new ShopConfigDO();
                    configDO.setId(x.getId());
                    configDO.setConfigValue(NumberUtils.generateCode(lenArr.get(0)));
                    configDO.setUpdateTime(new Date());
                    configDO.setUpdateBy("系统定时刷新");
                    backShopConfigMapper.updateByPrimaryKeySelective(configDO);
                }
            });
        }
        return AjaxResult.success("刷新成功！");
    }

    /**
     * 刷新优惠券状态
     *
     * @return
     */
    @GetMapping("/expireCouponRemind/{shopId}")
    public AjaxResult expireCouponRemind(@PathVariable("shopId") Long shopId) {
        String configVal = backShopConfigMapper.searchValueByKey(SysConfigConstants.ShopConfigEnum.WXNOTIFY_SWITCH_COUPON2.getKey(), shopId);
        if (!UserConstants.YES.equals(configVal)) {
            return AjaxResult.error("到期提醒开关未开启！");
        }
        String expireRemindAt = backShopConfigMapper.searchValueByKey(SysConfigConstants.ShopConfigEnum.WXNOTIFY_COUPON_EXPIRE_REMIND_AT.getKey(), shopId);
        if (StringUtils.isEmpty(expireRemindAt)) {
            expireRemindAt = SysConfigConstants.ShopConfigEnum.WXNOTIFY_COUPON_EXPIRE_REMIND_AT.getDefaultValue();
        }
        //TODO:模板消息写入
        List<HashMap<String, String>> wxNotifyParamList = new ArrayList<>();
        //TODO:找出还有
        List<MemberCouponVO> memberCouponList = memberCouponMapper.searchExpireRemindList(shopId, expireRemindAt);
        if (memberCouponList.size() > 0) {
            for (MemberCouponVO one : memberCouponList
            ) {
                HashMap<String, String> wxNotifyParam = new HashMap<>();
                wxNotifyParam.put("templateKey", "couponExpire");
                wxNotifyParam.put("title", one.getTitle());
                wxNotifyParam.put("shopId", shopId.toString());
                wxNotifyParam.put("openid", one.getOpenid());
                if (one.getCouponType() == CouponConstants.TypeEnum.FACE_VALUE.getValue()) {
                    wxNotifyParam.put("discountValueDesc", one.getFaceValue() + "元");
                } else {
                    wxNotifyParam.put("discountValueDesc", one.getDiscount().multiply(BigDecimal.TEN).setScale(1, BigDecimal.ROUND_HALF_UP).toString() + "折");
                }
                wxNotifyParam.put("remark", "你的优惠券还有" + expireRemindAt + "天过期，请及时使用");
                wxNotifyParam.put("useEndTime", DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, one.getUseEndTime()));
                wxNotifyParamList.add(wxNotifyParam);
            }
        }
        //批量消息通知
        for (HashMap<String, String> one : wxNotifyParamList
        ) {
            AsyncManager.me().execute(AsyncFactory.sendWechatTemplateNotify(one));
        }
        return AjaxResult.success("提醒成功！");
    }
}
